Jump to content
  • 0

ODBC en bvb global fields


elmystica

Question

ODBC zal hier wel een beetje mijn thema worden, vrees ik :?

 

We willen een website beheren vanuit FM.

De klant beheert alles binnen zijn bedrijf vanuit een Filemaker Pro oplossing. Producten, klanten, communicaties, inventarisatie, verkoop, bestellingen, marketing, ...

 

Nu willen we dus een oplossing opzetten voor een bepaalde categorie van producten. Daarvoor komt een website waarop mensen zaken kunnen kijken en vergelijken, afspraken boeken voor bepaalde producten te bekijken, toestellen reserveren, ..

 

Enerzijds gaan we dus producten die in de huidige oplossing zitten 'pushen' naar de website, anderzijds moeten we dus die klanten en hun keuzes etc gaan binnen halen in FMP.

 

Nu vroeg ik me af hoe jullie hiervoor te werk gaan.

 

Werken jullie altijd op die "live" MySQL-tabellen?

Het voordeel lijkt me dan dat je inderdaad steeds de meest recente data hebt, zonder extra scripts. Anderzijds heb je dan het nadeel dat gebruikers records heel vlot "per ongeluk" kunnen wissen op de website. Je kan ook geen global Fields toevoegen aan je MySQL TO's, iets wat ik toch vrij vaak gebruik in FM.

 

Of doen jullie dan steeds een importscript?

Waarbij een TO gebaseerd op een tabel aangemaakt in FM wordt gesynchroniseerd met een TO van een MySQLgebaseerde tabel?

Dat worden volgens mij ook heel wat extra stappen voor bvb records opslaan en tables syncen...?

Momenteel doen we voor een andere toepassing al een export van ongeveer vierhonderd records met een vijftiental velden, en dan duurt het een minuut ongeveer om alles te exporteren naar MySQL, vermoedelijk wordt dat toch wel te belastend als we dat frequent willen doen.

Link to comment

3 answers to this question

Recommended Posts

  • 0

Hoi Elmystica,

 

dat zijn heel wat vragen. Er zijn verschillende opslossingen en aanvliegroutes denkbaar. Eerst wat (startup) statements:

- Ten eerste denk ik dat je altijd goed is in de SQL-web omgeving om die data apart te houden van je filemaker oplossing. Zo'n site moet autonoom draaien en als er iets gehacked zou worden is het alleen de website data die op het spel staat en niet alle back-office data.

- In SQL-webland is het aan te raden een testomgeving naast de productie omgeving te houden. Dit voor het uitbannen van bugs voordat je de nieuwe 'site' live zet. Ff een testlayout en een setje testscripts gebaseerd op de zelfde TO is niet zo makkelijk in SQL-web land.

- Ik geef de voorkeur om een omgeving aan te spreken in de native tongue.. Dat betekend dus queries maken in variabelen en die netjes 'executeer'. Er zijn andere ontwikkelaars die juist zeggen blijf binnen de oplossingen die filemaker biedt en dat betekent dat je in de SQL-table occurance nieuwe records aanmaakt ipv een querie wegzet.

 

Er zijn velden (zoals blobs) die je niet via filemakers TO's kunt bedienen. Zowiezo is uploaden van plaatjes blijkbaar nogal exotisch maar dat zal ik hier niet bespreken.

 

Bij één specifieke klant uploaden data voor (web)producten via een echte query (12 verschillende tabellen + plaatjes) en die bekijk ik weer via een SQL-TO van de tabellen-set die ik net heb geupload. Omdat het meerdere tabellen zijn moet je de hoofdtabellen eerst doen en dat subtabellen er na, anders regent het ODBC-errors.

Op de terugweg gebruiken we alleen de SQL-TO om data uit te halen (web-oders). We hadden grote problemen met het wissen van records (in de SQL-tabel) via SQL-TO maar dat bleek een rechten probleem te zijn. Mijn neiging om de delete via een query te doen was erg groot maar bleek niet nodig.

 

Zie het als een casus. Voor echt veel data heen en weer schieten zeggen de specialisten dat je beter via een web-server php-calls naar de fm-server kunt doen om data van en naar de fm-databases te schieten (oplossing bij een andere klant). Dat betekend dat je alle script logica herschrijft in php-code, je beschikt dan over alle velden en layout's binnen je fm-oplossing maar die spreek je dan aan vanuit php-calls.

 

Ik hoop dat ik met dit relaas je vragen enigszins heb beantwoord.

Link to comment
  • 0

Nou, dat is een verrijkende reactie! Super!

 

Er zijn inderdaad een aantal scenario's die iet of wat door elkaar lopen.

Enerzijds is er de productcatalogus. Daarin worden af en toe records aangemaakt, bijgewerkt, ... Daarvoor ga ik een script uitwerken dat in een eigen logtabel kijkt wanneer de laatste queries uitgevoerd werden, kijkt welke producten een update-timestamp hebben en daarvan een update doen, en nieuwe dan toevoegen. Daarvoor zou ik inderdaad met queries werken. (mogelijks hou ik wel een MySQL TO van wat er nu al in zit, omdat tussen aanmaak en update er bvb nog geen query uitgevoerd is, maar er intussen wel al een updatetimestamp is).

 

Foto's zijn niet zo'n probleem: momenteel loopt er een applicatie waarbij een foto in een mini-fotostudio getrokken wordt, en via Filemaker en Applescripts (wat helaas slechte feedback geeft :( ) al drie maten foto's online geraken.

 

Anderzijds zijn er de klanten en hun "acties". Dat is voor 90% data die enkel binnen dient te komen, waarvoor minder wordt terug gestuurd naar de website. Omdat mijn klant zo snel mogelijk wil inspelen op klanten (tijdens openingsuren), wil hij liefst constant live data zien. Als ik lay-outs maak op MySQL-TO's dan heb ik inderdaad live data, maar dan moet ik een window refresh doen die regelmatig alles opnieuw ophaalt. Hinderlijk als ze dan net allemaal data aan het verwerken zijn, bvb. Ik zou dan inderdaad een serverside PHP-API kunnen uitwerken en die aanroepen vanuit FM, maar dat wordt dan nog even uitzoeken hoe dat gaat binnen FM. Vandaar dat ik toch die MySQL-TO zou verkiezen. Het wordt nog even alles uittesten, denk ik.

 

Delete-acties wil ik eigenlijk wel ergens gaan vermijden. FM maakt het heel makkelijk een record te verwijderen, en als dat met MySQL data van een klant is, oogt dat niet bepaald goed. Waar we dat willen vermijden, maken we een MySQL-user die niks kan verwijderen en wordt een delete eigenlijk vertaald naar een "flag_active = 0". Ook in FM maken we dan gebruikers aan die niks kunnen wissen, enkel de flag aanpassen.

 

Bedankt voor de aanzet tot een intense denkoefening!

Link to comment
  • 0

Zo, intussen begonnen aan het uitwerken ervan.

 

Ik heb daar twee vraagjes bij ... :oops:

 

1. Ik heb het scriptje (in opbouw) hierbij gestoken. Welke verbeteringen zijn er volgens jullie op het eerste zicht nodig?

Het is het eerste grotere project dat ik maak, dus eigenlijk nog wat nieuw. Ik probeer enkele adviezen in functie van snelheid ed. wat in gedachten te houden. Zo probeer ik te vermijden om naar records te gaan voor bewerkingen en dergelijke. Ook spreek ik liever rechtstreeks de oorspronkelijke MySQL table aan, ipv een TO van een ODBC-bron.

 

2. Zoals je merkt, zijn er heel wat velden in die table. Als ik door mijn reeks records loop, wil ik ze in die loop gaan controleren of ze bestaan. Zoniet voegt hij ze toe. En anders kijkt hij of ze recenter dan de laatste sync een update kregen. Moet ik hiervoor telkens elk veld in een variabele stoppen (set variable, executeSql functie die veldinhoud opvraagt)? En dan in de Execute SQL gaan invoegen? Of hoe pak ik dat efficiënter aan? Nu neemt hij enkel de eerste record. Ik snap niet goed hoe die getNthRecord in zo een situatie gebruikt wordt, namelijk.

 

# 
# 20140705 - Michel Beyaert - init script
# 
# Script checks if a record exists online.
# If it doesn't exist, upload it.
# If it does exist, checks if the last date in the synclog table is older. If it is, it updates, otherwise, leave like it is.
# 
# Get last product syncdate & current date
Variabele instellen [ $last_sync_stamp; Waarde:GetValue ( ExecuteSQL ( "SELECT \"_crea_date\" from \"_syncs\" ORDER BY \"_crea_date\" DESC" ; ""; "") ; 1 ) ]
#
# Make sure the ess products-table is up to date
Venster vastzetten
Ga naar lay-out [ “essPROD” (essPROD) ]
Venster vernieuwen
[ Samenvoegresultaten in cache wissen; Externe gegevens in cache wissen ] Ga naar lay-out [ originele lay-out ]
#
# Get all the product record ID's
Variabele instellen [ $recordIDs; Waarde:List ( dashprod_PROD::_k1_productid ) ] 
Variabele instellen [ $total; Waarde:ValueCount ( $recordIDs ) ]
Variabele instellen [ $count_inserted_records; Waarde:0 ]
Variabele instellen [ $count_updated_records; Waarde:0 ]
Variabele instellen [ $i; Waarde:1 ]
#
# Start Loop
Loop
#
# Does record exist online?
Variabele instellen [ $recordid; Waarde:If ( IsEmpty ( ExecuteSQL ( "SELECT * from essPROD WHERE recordid = ? " ; "";""; GetValue ($recordIDs; $i) ) ); False; True )]
#
If [ $recordid = False ] 
#
# No: create it online
SQL uitvoeren [ ODBC-gegevensbron: “NatuurCombell”; Berekende SQL-tekst: "INSERT INTO optiek_catalogus_beta
(
recordid,
behuizing,
beschikbaar,
coating,
diameter_objectief,
dioptriecompensatie,
garantie,
gewicht,
gezichtsveld_graden,
gezichtsveld_op_1000m,
korste_scherpstelafstand,
merk,
prijs,
nettoprijs,
productomschrijving, 
type,
accessoire, 
vergroting, 
waterdichtheid, 
serie
)
VALUES (
'" & dashprod_PROD::_k1_productid & "',
'" & dashprod_PROD::casing & "' ,
'" & dashprod_PROD::stock & "' ,
'" & dashprod_PROD::coating & "' ,
'" & dashprod_PROD::diameter_lens & "' ,
'" & dashprod_PROD::diopter_compensation & "' ,
'" & dashprod_PROD::warranty & "' ,
'" & dashprod_PROD::weight & "' ,
'" & dashprod_PROD::field_degrees & "' ,
'" & dashprod_PROD::field_1000m & "' ,
'" & dashprod_PROD::shortest_focus_distance & "' ,
'" & dashprod_PROD::brand & "' ,
'" & dashprod_PROD::price_general & "' ,
'" & dashprod_PROD::price_net & "' ,
'" & dashprod_PROD::name & "' ,
'" & dashprod_PROD::type & "' ,
'" & dashprod_PROD::accessorie & "' ,
'" & dashprod_PROD::magnification & "' ,
'" & dashprod_PROD::waterproof & "' ,
'" & dashprod_PROD::serie & "'
)" ]
[ Geen dialoogvenster ]
Variabele instellen [ $count_inserted_records; Waarde:$count_inserted_records + 1 ] 
#
# No: Do nothing
Else
#
# Has it been updated after last sync?
Variabele instellen [ $last_updated; Waarde:GetValue ( ExecuteSQL ( "SELECT \"_mod_date\" from dashprod_PROD WHERE \"_k1_productid\" = ?"; ""; "" ; GetValue ($recordIDs; $i) ); 1 ) ]
If [ $last_sync_stamp ≤ $last_updated ] 
#
# Yes: Update current record in online database
SQL uitvoeren [ ODBC-gegevensbron: “NatuurCombell”; Berekende SQL-tekst: "UPDATE optiek_catalogus_beta
SET
behuizing = '" & dashprod_PROD::casing & "' ,
beschikbaar = '" & dashprod_PROD::stock & "' ,
coating = '" & dashprod_PROD::coating & "' ,
diameter_objectief = '" & dashprod_PROD::diameter_lens & "' , 
dioptriecompensatie = '" & dashprod_PROD::diopter_compensation & "' , 
garantie = '" & dashprod_PROD::warranty & "' ,
gewicht = '" & dashprod_PROD::weight & "' ,
gezichtsveld_graden = '" & dashprod_PROD::field_degrees & "' , 
gezichtsveld_op_1000m = '" & dashprod_PROD::field_1000m & "' , 
korste_scherpstelafstand = '" & dashprod_PROD::shortest_focus_distance & "' , 
merk = '" & dashprod_PROD::brand & "' ,
prijs = '" & dashprod_PROD::price_general & "' ,
nettoprijs = '" & dashprod_PROD::price_net & "' ,
productomschrijving = '" & dashprod_PROD::name & "' ,
type = '" & dashprod_PROD::type & "' ,
accessoire = '" & dashprod_PROD::accessorie & "' ,
vergroting = '" & dashprod_PROD::magnification & "' ,
waterdichtheid = '" & dashprod_PROD::waterproof & "' ,
serie = '" & dashprod_PROD::serie & "'
WHERE recordid = " & GetValue ( $recordIDs; $i ) ] [ Geen dialoogvenster ]
Variabele instellen [ $count_updated_records; Waarde:$count_updated_records + 1 ]
#
Else
#
Aangepast dialoogvenster tonen [ Titel: "_log"; Bericht: $last_sync_stamp & " >= " & $last_updated & ¶ &
"Record updated before last sync"; Standaardknop: “OK”, Vastleggen: “Ja” ]
End If 
End If
#
# If loopcounter is equal to total amount of records, exit, otherwise, add one more to the counter ... Exit Loop If [ $i = $total ]
Variabele instellen [ $i; Waarde:$i + 1 ]
End Loop
#
# Make a new record in our sync table 
# TODO
#

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...